package com.um.swing.common.util;

import cn.hutool.core.img.GraphicsUtil;

import java.awt.*;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;
import java.io.IOException;

public class ImageUtil {


    /**
     * 计算旋转后的图片尺寸
     *
     * @param width  宽度
     * @param height 高度
     * @param degree 旋转角度
     * @return 计算后目标尺寸
     * @since 4.1.20
     */
    private static Rectangle calcRotatedSize(int width, int height, double degree) {
        if (degree < 0) {
            // 负数角度转换为正数角度
            degree += 360;
        }
        if (degree >= 90) {
            if (degree / 90 % 2 == 1) {
                int temp = height;
                //noinspection SuspiciousNameCombination
                height = width;
                width = temp;
            }
            degree = degree % 90;
        }
        double r = Math.sqrt(height * height + width * width) / 2;
        double len = 2 * Math.sin(Math.toRadians(degree) / 2) * r;
        double angel_alpha = (Math.PI - Math.toRadians(degree)) / 2;
        double angel_dalta_width = Math.atan((double) height / width);
        double angel_dalta_height = Math.atan((double) width / height);
        int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));
        int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));
        int des_width = width + len_dalta_width * 2;
        int des_height = height + len_dalta_height * 2;

        return new Rectangle(des_width, des_height);
    }

    //旋转图片
    public static Image rotate(Image image, double degree) {
        int width = image.getWidth(null);
        int height = image.getHeight(null);
        final Rectangle rectangle = calcRotatedSize(width, height, degree);
        final BufferedImage targetImg = new BufferedImage(rectangle.width, rectangle.height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics2d = targetImg.createGraphics();
        // 抗锯齿
        graphics2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        // 从中心旋转
        graphics2d.translate((rectangle.width - width) / 2D, (rectangle.height - height) / 2D);
        graphics2d.rotate(Math.toRadians(degree), width / 2D, height / 2D);
        graphics2d.drawImage(image, 0, 0, null);
        graphics2d.dispose();
        return targetImg;
    }

    /**
     * @param mini  贴图
     * @param ratio 旋转角度
     * @return
     */

    public static BufferedImage modifyImageRatio(BufferedImage mini, double ratio, Point centerPoint) {
        int src_width = mini.getWidth();
        int src_height = mini.getHeight();
        //针对图片旋转重新计算图的宽*高
        Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), ratio);
        rect_des.width+= 100;//无奈之举，由于是要按照指定点位进行旋转，但是计算宽高算法却没有，导致宽度有误差
        //设置生成图片的宽*高，色彩度
        BufferedImage res = new BufferedImage(rect_des.width, rect_des.height, BufferedImage.TYPE_INT_RGB);
        //创建画布
//        Graphics2D g2 = res.createGraphics();
        Graphics2D g2 = GraphicsUtil.createGraphics(res, Color.BLUE);
        res = g2.getDeviceConfiguration().createCompatibleImage(rect_des.width, rect_des.height, Transparency.TRANSLUCENT);
        g2 = res.createGraphics();
        g2.setStroke(new BasicStroke(3.5f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //重新设定原点坐标
//        g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);
        //执行图片旋转，rotate里包含了translate，并还原了原点坐标
        g2.rotate(Math.toRadians(ratio), centerPoint.x, centerPoint.y);
        g2.drawImage(mini, null, null);
        g2.dispose();
        return res;
    }

    private static Rectangle CalcRotatedSize(Rectangle src, double angel) {

        if (angel >= 90) {

            if (angel / 90 % 2 == 1) {

                int temp = src.height;

                src.height = src.width;

                src.width = temp;

            }

            angel = angel % 90;

        }

        double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;

        double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;

        double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;

        double angel_dalta_width = Math.atan((double) src.height / src.width);

        double angel_dalta_height = Math.atan((double) src.width / src.height);

        int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));

        int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));

        int des_width = src.width + len_dalta_width * 2;

        int des_height = src.height + len_dalta_height * 2;

        return new Rectangle(new Dimension(des_width, des_height));

    }


    /**
     * 裁剪(多边形)
     *
     * @param inputFilePath 图片输入路径
     * @param outFilePath   图片输出路径
     * @param x[]           x轴坐标点数组
     * @param y[]           y轴坐标点数组
     * @param n             坐标点数量
     * @return
     * @throws IOException
     */
    public static BufferedImage cutPolygon_Image(BufferedImage image, int[] x,
                                                 int[] y, int n) throws IOException {
        try {
            GeneralPath clip = new GeneralPath(GeneralPath.WIND_EVEN_ODD, n);
            //int x[]={860,650,300,1700};
            //int y[]={20,20,1000,1000};
            clip.moveTo(x[0], y[0]);
            for (int i = 1; i < x.length; i++) {
                clip.lineTo(x[i], y[i]);
            }
            clip.closePath();

            Rectangle bounds = clip.getBounds();
            BufferedImage img = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
//            BufferedImage img = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_BGR);
            Graphics2D g2d = img.createGraphics();
            //clip.transform(AffineTransform.getTranslateInstance(0, 0));
            g2d.setClip(clip);
            //g2d.translate(0, 0);
//            g2d.setColor(Color.BLUE);
//            g2d.setStroke(new BasicStroke(10));
//            g2d.drawLine(248,1000,2000,1200);
//            g2d.drawPolyline(x,y,n);
            g2d.drawImage(image, 0, 0, null);
            g2d.dispose();
            return img;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
